/***************************************************************************************************
 *Copyright(C),2010-2016,Sumscope
 *FileName	:  pinyin_search.cpp
 *Author	:  scofined.qi
 *Version	:  1.0
 *Date		:  2017/06/04
 *Desc		:
 *Relation :
 *Others	:
 *Function :
 *History	:
 ***************************************************************************************************/
#include "pinyin_search.h"

#include <algorithm>

#include "../strings/string_page.h"
#include "./pinyin/pinyin_search_buffer.h"
#include "./pinyin/pinyin_search_engine.h"
#include "pinyin.h"

#ifdef WIN32
#include <process.h>
#endif

#define ROUND_ALIGN(NUM, SIZE) \
  ((NUM % SIZE == 0) ? NUM : ((NUM / SIZE + 1) * SIZE))

namespace qb {
namespace base {
namespace {
ISpellSearch* GetSearchEngine() {
  return internal::SpellSearchImpl::instance();
}
}  // namespace
typedef internal::BondChangeBuffer BondChangeBuffer;
/////////////////////////////////////////////////////////////////////////////
SpellSearch::Collector::Collector(bool build)
    : m_buffer(NULL), m_count(0), m_build(build), m_diskless(false) {}
SpellSearch::Collector::~Collector() {
  BondChangeBuffer* buffer = (BondChangeBuffer*)m_buffer;
  if (buffer) {
    delete buffer;
  }
  if (m_build) GetSearchEngine()->BuildIndex(m_diskless);
}
void SpellSearch::Collector::AddChange(int id, int type, const char* oldName,
                                       int oldlen, const char* name, int len) {
  if (strcmp(oldName, name) == 0) return;
  m_count++;
  ((BondChangeBuffer*)GetBuffer())
      ->AddChange(id, (kChangeType)type, oldName, oldlen, name, len);
}
void SpellSearch::Collector::AddNameChange(int id, const char* oldName,
                                           int oldlen, const char* name,
                                           int len) {
  if (strcmp(oldName, name) == 0) return;
  m_count++;
  ((BondChangeBuffer*)GetBuffer())
      ->AddNameChange(id, oldName, oldlen, name, len);
}
void SpellSearch::Collector::AddNameEnChange(int id, const char* oldName,
                                             int oldlen, const char* name,
                                             int len) {
  if (strcmp(oldName, name) == 0) return;
  m_count++;
  ((BondChangeBuffer*)GetBuffer())
      ->AddNameEnChange(id, oldName, oldlen, name, len);
}
void SpellSearch::Collector::AddCodeChange(int id, const char* oldCode,
                                           int oldlen, const char* code,
                                           int len) {
  if (strcmp(oldCode, code) == 0) return;
  m_count++;
  ((BondChangeBuffer*)GetBuffer())
      ->AddCodeChange(id, oldCode, oldlen, code, len);
}

void SpellSearch::Collector::Commit() {
  if (m_buffer != NULL) {
    BondChangeBuffer* buffer = (BondChangeBuffer*)m_buffer;
    GetSearchEngine()->AddBondChange(buffer);
    buffer->Reset();
  }
  m_count = 0;
}
void* SpellSearch::Collector::GetBuffer() {
  if (m_buffer == NULL) m_buffer = new BondChangeBuffer();
  return m_buffer;
}

void SpellSearch::GetPinyinBuffer(const wchar_t* buffer, int len,
                                  wchar_t* quanbuf, int& quanlen,
                                  wchar_t* jianbuf, int& jianlen) {
  Spell::Parse(buffer, len, quanbuf, quanlen, jianbuf, jianlen);
}

void SpellSearch::GetAllKeys(std::vector<std::wstring>& keys) {
  GetSearchEngine()->GetAllKeys(keys);
}
void SpellSearch::FindBonds(const std::wstring& text, Listener* listener) {
  GetSearchEngine()->FindBonds(text, listener);
}
void SpellSearch::FindBonds(unsigned short const* text, int len,
                            Listener* listener) {
  if (text && len >= 0)
    GetSearchEngine()->FindBonds(std::wstring((const wchar_t*)text, len),
                                 listener);
}
}  // namespace base
}  // namespace qb
